using Beauty.Net.Consul.Core;
using Consul;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;

namespace Beauty.Net.Consul;

/// <summary>
/// Consul服务集合扩展
/// </summary>
public static class ConsulServiceCollectionExtensions
{
    /// <summary>
    /// 添加Consul服务
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="configuration">配置对象</param>
    /// <param name="sectionName">配置节名称</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddConsul(
        this IServiceCollection services,
        IConfiguration configuration,
        string sectionName = "Consul")
    {
        // 绑定配置
        services.Configure<ConsulOptions>(configuration.GetSection(sectionName));
        
        // 注册Consul客户端
        services.AddSingleton<IConsulClient, ConsulClient>(sp =>
        {
            var options = sp.GetRequiredService<IOptions<ConsulOptions>>().Value;
            return new ConsulClient(config =>
            {
                config.Address = new Uri(options.Address);
            });
        });
        
        // 注册服务发现服务
        services.AddSingleton<IConsulDiscoveryService, ConsulDiscoveryService>();
        
        // 注册Consul托管服务（用于服务注册）
        services.AddHostedService<ConsulHostedService>();
        
        return services;
    }
    
    /// <summary>
    /// 添加Consul服务（使用配置委托）
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="configureOptions">配置委托</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection AddConsul(
        this IServiceCollection services,
        Action<ConsulOptions> configureOptions)
    {
        // 配置选项
        services.Configure(configureOptions);
        
        // 注册Consul客户端
        services.AddSingleton<IConsulClient, ConsulClient>(sp =>
        {
            var options = sp.GetRequiredService<IOptions<ConsulOptions>>().Value;
            return new ConsulClient(config =>
            {
                config.Address = new Uri(options.Address);
            });
        });
        
        // 注册服务发现服务
        services.AddSingleton<IConsulDiscoveryService, ConsulDiscoveryService>();
        
        // 注册Consul托管服务（用于服务注册）
        services.AddHostedService<ConsulHostedService>();
        
        return services;
    }
    
    /// <summary>
    /// 配置Consul服务地址和端口
    /// </summary>
    /// <param name="services">服务集合</param>
    /// <param name="hostEnvironment">主机环境</param>
    /// <returns>服务集合</returns>
    public static IServiceCollection ConfigureConsulServiceAddress(
        this IServiceCollection services,
        IHostEnvironment hostEnvironment)
    {
        services.PostConfigure<ConsulOptions>(options =>
        {
            // 如果没有指定服务地址，则使用主机名或IP
            if (string.IsNullOrEmpty(options.ServiceAddress))
            {
                // 开发环境使用localhost，生产环境获取主机名
                options.ServiceAddress = hostEnvironment.IsDevelopment() 
                    ? "localhost" 
                    : Environment.MachineName;
            }
        });
        
        return services;
    }
}